package com.vincenzofehring.theologist;

import com.vincenzofehring.theologist.service.MLDatabase;
import com.vincenzofehring.theologist.service.utils.CatalogManagerJob;
import com.vincenzofehring.theologist.service.utils.DownloadManager;
import com.vincenzofehring.theologist.util.LanguageUtil;
import com.vincenzofehring.theologist.util.WebServiceException;

import android.app.Application;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;

/**
 * Helps us manage the book download queue and populating the manage library cache
 *
 * @author: Vincenzo Fehring
 */
public class TheologistLibraryApplication extends Application {
	
	private static final String APP_NAME = "THEOLOGIST_LIBRARY_APP";
	
	/**
	 * Our authority for this content provider.
	 */
	public static final String AUTHORITY = "com.vincenzofehring.theologist";
	
	/**
	 * Base content URI for this content provider.
	 */
	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
	
	/**
	 * Debug flag for wrapping log statements and other things which should
	 * be excluded from release.
	 */
	 public static final boolean DEBUG = true;
	 
	 private static MLDatabase mlDatabase;
	 
	 // Catalog data
	 private volatile Handler mUiHandler;
	 private volatile Thread mUiThread;
	 
	 /*
	  * (non-Javadoc)
	  * @see android.app.Application#onCreate()
	  */
	 @Override
	 public void onCreate() {
		 enableStrictMode();
		 super.onCreate();
		 if (TheologistLibraryApplication.DEBUG){
			 Log.d(APP_NAME, "APPLICATION onCreate");
		 }
		 mlDatabase = new MLDatabase(this);
		 mUiHandler = new Handler();
		 mUiThread = Thread.currentThread();
		 
		 CatalogManagerJob catalogManager = CatalogManagerJob.getInstance(this);
		 catalogManager.refreshCatalog(LanguageUtil.getPreferredLanguageId(this),true, false, false);
		 
		 DownloadManager.getInstance(this); // this simply creates the instance and will start the thread
	 }
	 
	 private void enableStrictMode() {
		 // this only works if compiling against android 2.3 or greater
		 //if (true) {
		 //	 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
		 //	 .detectDiskReads()
		 //	 .detectDiskWrites()
		 //	 .detectNetwork() // or .detectAll() for all detectable problems
		 //	 .penaltyLog()
		 //	 .build());
		 //	 StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
		 //	 .detectLeakedSqlLiteObjects()
		 //	 .penaltyLog()
		 //	 .penaltyDeath()
		 //	 .build());
		 //}
	 }
	 
	 /* (non-Javadoc)
	  * @see android.app.Application#onTerminate()
	  */
	 @Override
	 public void onTerminate() {
		 if (TheologistLibraryApplication.DEBUG) {
			 Log.d(APP_NAME, "APPLICATION onTerminate");
		 }
		 super.onTerminate();
	 }
	 
	 /**
	  * @return the mlDatabase
	  */
	 public MLDatabase getMlDatabase() {
		 if (mlDatabase == null) {
			 mlDatabase = new MLDatabase(this);
		 }
		 return mlDatabase;
	 }
	 
	 /**
	  * Runs the specified action on the UI thread. If the current thread is the UI
	  * thread, then the action is executed immediately. If the current thread is
	  * not the UI thread, the action is posted to the event queue of the UI thread.
	  * 
	  * @param action - the action to run on the UI thread
	  */
	 public final void runOnUiThread(Runnable action) {
		 if (Thread.currentThread() != mUiThread) {
			 mUiHandler.post(action);
		 } else {
			 action.run();
		 }
	 }
	 
	 public void showToast(final String message, final int duration) {
		 runOnUiThread(new Runnable() {
			 public void run() {
				 Toast.makeText(TheologistLibraryApplication.this, message, duration).show();
			 }
		 });
	 }
	 
	 public void showToast(final int resId, final int duration) {
		 runOnUiThread(new Runnable() {
			 public void run() {
				 Toast.makeText(TheologistLibraryApplication.this, resId, duration).show();
			 }
		 });
	 }
	 
	 public void showWebServiceExceptionToast(final WebServiceException e) {
		 int resId = R.string.webservice_generic_error;
		 
		 if (e != null && e.getErrorType() == WebServiceException.ErrorType.NO_NETWORK) {
			 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
			 boolean cellularUseMode = prefs.getBoolean(Preferences.KEY_CELLULAR_USE_MODE, false);
			 if (!cellularMode) {
				 resId = R.string.network_wifi_required;
			 }
			 else {
				 resId = R.string.network_required;
			 }
		 }
		 
		 showToast(resId, Toast.LENGTH_LONG);
	 }
	 
	 public Thread getUiThread() {
		 return mUiThread;
	 }
	 
	 public boolean isThereContentDialog()
	 {
		 // If the app has never been loaded before display this dialog
		 if (mlDatabase.queryBooksOnDeviceCount() == 0)
			 return false;
		 else
			 return true;
	 }
}